package com.jianjun.framework.web.handler;

import cn.hutool.http.HtmlUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;

/**
 * xss过滤处理
 * @author source
 * {@code @date} 2025/1/17 15:09
 */

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    private static String getBasicHtmlandimage(String html) {
        if (html == null) {
            return null;
        }
        return HtmlUtil.filter(html);
    }

    /**
     * 重写并过滤getParameter方法
     */
    @Override
    public String getParameter(String name) {
        return getBasicHtmlandimage(super.getParameter(name));

    }

    /**
     * 重写并过滤getParameterValues方法
     */
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (null == values) {
            return null;
        }
        for (int i = 0; i < values.length; i++) {
            values[i] = getBasicHtmlandimage(values[i]);
        }
        return values;
    }

    /**
     * 重写并过滤getParameterMap方法
     */
    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> paraMap = super.getParameterMap();
        // 对于paraMap为空的直接return
        if (null == paraMap || paraMap.isEmpty()) {
            return paraMap;
        }

        //super.getParameterMap()不允许任何修改，所以只能做深拷贝
        //实际上putAll只对基本类型深拷贝有效，如果是自定义类型，则要找其他办法
        Map<String, String[]> paraMapCopy = new HashMap<>(paraMap);

        for (Map.Entry<String, String[]> entry : paraMapCopy.entrySet()) {
            String[] values = entry.getValue();
            if (null == values) {
                continue;
            }
            String[] newValues = new String[values.length];
            for (int i = 0; i < values.length; i++) {
                newValues[i] = getBasicHtmlandimage(values[i]);
            }
            entry.setValue(newValues);
        }
        return paraMapCopy;
    }
}